package ai.weed.qrcode.service;

import ai.weed.qrcode.domain.DrugInfo;
import ai.weed.qrcode.domain.dto.GoodData;
import ai.weed.qrcode.domain.dto.GoodResult;
import ai.weed.qrcode.domain.queryparam.DrugInfoQueryParam;
import ai.weed.qrcode.mapper.DrugInfoMapper;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.taobao.api.ApiException;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.request.AlibabaAlihealthDrugtraceTopYljgQueryCodedetailRequest;
import com.taobao.api.response.AlibabaAlihealthDrugtraceTopYljgQueryCodedetailResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * 药品  服务
 *
 * @author zhong.wang
 * @date 2025/11/3
 **/
@Service
public class DrugService {

    @Value("${taobao.url}")
    private String url;

    @Value("${taobao.appkey}")
    private String appkey;

    @Value("${taobao.secret}")
    private String secret;

    @Value("${taobao.refEntId}")
    private String refEntId;

    @Value("${mxnzp.appId}")
    private String appId;

    @Value("${mxnzp.appSecret}")
    private String appSecret;

    @Value("${mxnzp.url}")
    private String mxnapUrl;
    @Resource
    private DrugInfoMapper drugInfoMapper;


    /**
     * 根据药品追溯码获取药品信息
     * @param code
     * @return
     * @throws ApiException
     */
    public DrugInfo getDrugInfoByCode(String code) throws ApiException {
        LambdaQueryWrapper<DrugInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DrugInfo::getCode,code);
        queryWrapper.eq(DrugInfo::getDelFlag,0);
        DrugInfo drugInfo = this.drugInfoMapper.selectOne(queryWrapper);
        if(Objects.nonNull(drugInfo)){
            return drugInfo;
        }
        // 长度为20 并且 开头数字是8开头是追溯码
        if(code.length() == 20 && code.startsWith("8")){
            TaobaoClient client = new DefaultTaobaoClient(url, appkey, secret);
            AlibabaAlihealthDrugtraceTopYljgQueryCodedetailRequest req = new AlibabaAlihealthDrugtraceTopYljgQueryCodedetailRequest();
            req.setRefEntId(refEntId);
            req.setCodes(code);
            AlibabaAlihealthDrugtraceTopYljgQueryCodedetailResponse rsp = client.execute(req);
            List<AlibabaAlihealthDrugtraceTopYljgQueryCodedetailResponse.CodeFullInfoDto> models = rsp.getResult().getModels();
            if(CollUtil.isNotEmpty(models)){
                AlibabaAlihealthDrugtraceTopYljgQueryCodedetailResponse.CodeFullInfoDto model = models.get(0);
                drugInfo = new DrugInfo();
                // 编码
                drugInfo.setCode(model.getCode());
                // 名称
                drugInfo.setName(model.getDrugEntBaseDTO().getPhysicName());
                // 生产日期
                String produceDateStr = model.getCodeProduceInfoDTO().getProduceInfoList().get(0).getProduceDateStr();
                Date produceDate = DateUtil.parse(produceDateStr);
                drugInfo.setProduceDate(produceDate);
                // 有效期
                String expireDateStr = model.getCodeProduceInfoDTO().getProduceInfoList().get(0).getExpireDate();
                Date expireDate = DateUtil.parse(expireDateStr);
                drugInfo.setExpireDate(expireDate);
                // 生产厂家
                drugInfo.setProducer(model.getpUserEntDTO().getEntName());
                // 批号
                drugInfo.setApprovalLicenceNo(model.getDrugEntBaseDTO().getApprovalLicenceNo());
                // 包装等级
                drugInfo.setPkgSpecCrit(model.getDrugEntBaseDTO().getPkgSpecCrit());
                // 描述
                drugInfo.setDescription(JSON.toJSONString(model));
            }
        }else if(code.length()==13 && code.startsWith("6")){
            // https://www.mxnzp.com/api/barcode/goods/details?barcode=6901404300854&app_id=fmgt9mjfhffixkqu&app_secret=WSJTpKH8t8Skj7nhO0eVb038FEz05vyp
            Map<String, Object> params = new HashMap<>();
            params.put("barcode", code);
            params.put("app_id", appId);
            params.put("app_secret", appSecret);
            String result = HttpUtil.get(mxnapUrl, params);
            GoodResult goodResult = JSON.parseObject(result, GoodResult.class);
            if(goodResult.getCode()==1){
                GoodData goodData = goodResult.getData();
                drugInfo.setCode(goodData.getBarcode());
                drugInfo.setName(goodData.getGoodsName());
                drugInfo.setPkgSpecCrit(goodData.getStandard());
                drugInfo.setProducer(goodData.getSupplier());
            }
        }

        return drugInfo;
    }
    /**
     * 同步药品信息
     * @param code
     * @throws ApiException
     */
    public void syncDrugInfo(String code) throws ApiException {
        TaobaoClient client = new DefaultTaobaoClient(url, appkey, secret);
        AlibabaAlihealthDrugtraceTopYljgQueryCodedetailRequest req = new AlibabaAlihealthDrugtraceTopYljgQueryCodedetailRequest();
        req.setRefEntId(refEntId);
        req.setCodes(code);
        AlibabaAlihealthDrugtraceTopYljgQueryCodedetailResponse rsp = client.execute(req);
        List<AlibabaAlihealthDrugtraceTopYljgQueryCodedetailResponse.CodeFullInfoDto> models = rsp.getResult().getModels();
        if(CollUtil.isNotEmpty(models)){
            for (AlibabaAlihealthDrugtraceTopYljgQueryCodedetailResponse.CodeFullInfoDto model : models) {
                DrugInfo drugInfo = new DrugInfo();
                // 编码
                drugInfo.setCode(model.getCode());
                // 名称
                drugInfo.setName(model.getDrugEntBaseDTO().getPhysicName());
                // 生产日期
                String produceDateStr = model.getCodeProduceInfoDTO().getProduceInfoList().get(0).getProduceDateStr();
                Date produceDate = DateUtil.parse(produceDateStr);
                drugInfo.setProduceDate(produceDate);
                // 有效期
                String expireDateStr = model.getCodeProduceInfoDTO().getProduceInfoList().get(0).getExpireDate();
                Date expireDate = DateUtil.parse(expireDateStr);
                drugInfo.setExpireDate(expireDate);
                // 生产厂家
                drugInfo.setProducer(model.getpUserEntDTO().getEntName());
                // 批号
                drugInfo.setApprovalLicenceNo(model.getDrugEntBaseDTO().getApprovalLicenceNo());
                // 包装等级
                drugInfo.setPkgSpecCrit(model.getDrugEntBaseDTO().getPkgSpecCrit());
                // 描述
                drugInfo.setDescription(JSON.toJSONString(model));
                this.saveOrUpdateByCode(drugInfo);
            }
        }
    }

    /**
     * 保存或更新
     * @param drugInfo
     */
    public void saveOrUpdateByCode(DrugInfo drugInfo) {
        LambdaQueryWrapper<DrugInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DrugInfo::getCode, drugInfo.getCode());
        queryWrapper.eq(DrugInfo::getDelFlag, 0);
        DrugInfo dbDrugInfo = drugInfoMapper.selectOne(queryWrapper);
        if(Objects.isNull(dbDrugInfo)){
            drugInfo.setCreateTime(new Date());
            drugInfo.setUpdateTime(new Date());
            drugInfoMapper.insert(drugInfo);

        }else{
            drugInfo.setId(dbDrugInfo.getId());
            drugInfo.setUpdateTime(new Date());
            drugInfoMapper.updateById(drugInfo);
        }
    }

    /**
     * 上传药品信息
     * @param drugInfo
     * @return
     */
    public boolean uploadDrugInfo(DrugInfo drugInfo){
        String code = generateUniqueCode(drugInfo);
        drugInfo.setCode(code);
        this.saveOrUpdateByCode(drugInfo);
        return true;
    }

    /**
     * 生成唯一编码
     * @param drugInfo
     * @return
     */
    private String generateUniqueCode(DrugInfo drugInfo) {
        // 格式化日期为字符串（确保一致性）
        String expireDateStr = drugInfo.getExpireDate() != null
                ? DateUtil.formatDate(drugInfo.getExpireDate())
                : "";

        // 拼接关键字段（建议用固定分隔符避免歧义）
        String source = String.join("|",
                drugInfo.getName() != null ? drugInfo.getName() : "",
                expireDateStr,
                drugInfo.getPkgSpecCrit() != null ? drugInfo.getPkgSpecCrit() : ""
        );

        // 使用 MD5 生成唯一标识（32位小写十六进制）
        return DigestUtil.md5Hex(source).toLowerCase();
    }
    /**
     * 查询
     * @return
     */
    public List<DrugInfo> list(DrugInfoQueryParam queryParam) {
        LambdaQueryWrapper<DrugInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StrUtil.isNotEmpty(queryParam.getName()),DrugInfo::getName,queryParam.getName());
        queryWrapper.like(StrUtil.isNotEmpty(queryParam.getCode()),DrugInfo::getCode,queryParam.getCode());
        queryWrapper.ge(Objects.nonNull(queryParam.getStartTime()),DrugInfo::getProduceDate,queryParam.getStartTime());
        queryWrapper.le(Objects.nonNull(queryParam.getEndTime()),DrugInfo::getProduceDate,queryParam.getEndTime());
        queryWrapper.eq(DrugInfo::getDelFlag, 0);
        queryWrapper.orderByAsc(DrugInfo::getExpireDate);
        return drugInfoMapper.selectList(queryWrapper);
    }

    /**
     * 删除
     * @param id
     * @return
     */
    public Integer deleteById(Long id) {
        LambdaUpdateWrapper<DrugInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(DrugInfo::getId, id);
        updateWrapper.set(DrugInfo::getDelFlag, 1);
        return drugInfoMapper.update(updateWrapper);
    }
}
